查看原文
其他

关于matplotlib,你要的饼图在这里

LEMON Python数据之道 2022-04-24

Table of Contents

1  官方Demo

2  将实际数据应用于官方Demo

3  一些改善措施

3.1  重新设置字体大小

3.2  设置显示颜色,Method 1:

3.3  设置显示颜色, Method 2:

3.4  设置图例(legend)

3.5  重新设置图例(legend)

3.6  将某些类别突出显示


# 前言

matplotlib, 官方提供的饼图Demo,功能比较比较简单,在实际应用过程中,往往会有许多个性化的绘制需求,在这里跟大家一起了解下饼图(pie chart)的一些特色的功能的实现。

  1. from matplotlib import font_manager as fm

  2. import matplotlib as mpl

  3. import pandas as pd

  4. import numpy as np

  5. import matplotlib.pyplot as plt

  6. % matplotlib inline

  7. plt.style.use('ggplot')

1. 官方Demo

  1. import matplotlib.pyplot as plt

  2. # Pie chart, where the slices will be ordered and plotted counter-clockwise:

  3. labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'

  4. sizes = [15, 30, 45, 10]

  5. explode = (0, 0.1, 0, 0)  # only "explode" the 2nd slice (i.e. 'Hogs')

  6. fig1, ax1 = plt.subplots()

  7. ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',

  8.        shadow=True, startangle=90)

  9. ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.

  10. plt.savefig('Demo_official.jpg')

  11. plt.show()

2. 将实际数据应用于官方Demo

  1. # 原始数据

  2. shapes = ['Cross', 'Cone', 'Egg', 'Teardrop', 'Chevron', 'Diamond', 'Cylinder',

  3.       'Rectangle', 'Flash', 'Cigar', 'Changing', 'Formation', 'Oval', 'Disk',

  4.       'Sphere', 'Fireball', 'Triangle', 'Circle', 'Light']

  5. values = [  287,   383,   842,   866,  1187,  1405,  1495,  1620,  1717,

  6.        2313,  2378,  3070,  4332,  5841,  6482,  7785,  9358,  9818, 20254]

  7. s = pd.Series(values, index=shapes)

  8. s

  1. from matplotlib import font_manager as fm

  2. import matplotlib as mpl

  3. # Pie chart, where the slices will be ordered and plotted counter-clockwise:

  4. labels = s.index

  5. sizes = s.values

  6. explode = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)  # only "explode" the 1st slice

  7. fig1, ax1 = plt.subplots()

  8. patches, texts, autotexts = ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.0f%%',

  9.        shadow=False, startangle=170)

  10. ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.

  11. plt.savefig('Demo_project.jpg')

  12. plt.show()


上图的一些问题:

  1. 颜色比较生硬

  2. 部分文字拥挤在一起,绘图显示不齐整

3. 一些改善措施

  • 重新设置字体大小

  • 设置自选颜色

  • 设置图例

  • 将某些类别突出显示

3.1 重新设置字体大小

  1. from matplotlib import font_manager as fm

  2. import matplotlib as mpl

  3. labels = s.index

  4. sizes = s.values

  5. explode = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)  # only "explode" the 1st slice

  6. fig1, ax1 = plt.subplots()

  7. patches, texts, autotexts = ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.0f%%',

  8.        shadow=False, startangle=170)

  9. ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.

  10. # 重新设置字体大小

  11. proptease = fm.FontProperties()

  12. proptease.set_size('xx-small')

  13. # font size include: ‘xx-small’,x-small’,'small’,'medium’,‘large’,‘x-large’,‘xx-large’ or number, e.g. '12'

  14. plt.setp(autotexts, fontproperties=proptease)

  15. plt.setp(texts, fontproperties=proptease)

  16. plt.savefig('Demo_project_set_font.jpg')

  17. plt.show()

3.2 设置显示颜色,Method 1:

  1. from matplotlib import font_manager as fm

  2. import matplotlib as mpl

  3. # Pie chart, where the slices will be ordered and plotted counter-clockwise:

  4. labels = s.index

  5. sizes = s.values

  6. explode = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)  # only "explode" the 1st slice

  7. fig1, ax1 = plt.subplots(figsize=(6,6)) # 设置绘图区域大小

  8. a = np.random.rand(1,19)

  9. color_vals = list(a[0])

  10. my_norm = mpl.colors.Normalize(-1, 1) # 将颜色数据的范围设置为 [0, 1]

  11. my_cmap = mpl.cm.get_cmap('rainbow', len(color_vals)) # 可选择合适的colormap,如:'rainbow'

  12. patches, texts, autotexts = ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.0f%%',

  13.        shadow=False, startangle=170, colors=my_cmap(my_norm(color_vals)))

  14. ax1.axis('equal')  

  15. # 重新设置字体大小

  16. proptease = fm.FontProperties()

  17. proptease.set_size('xx-small')

  18. # font size include: ‘xx-small’,x-small’,'small’,'medium’,‘large’,‘x-large’,‘xx-large’ or number, e.g. '12'

  19. plt.setp(autotexts, fontproperties=proptease)

  20. plt.setp(texts, fontproperties=proptease)

  21. plt.savefig('Demo_project_set_color_1.jpg')

  22. plt.show()

上面这种方法设置颜色时,但类别比较多时,部分颜色的填充会重复。

有时候,我们可能想设置成连续的颜色,可以有另外一种方法来实现。

3.3 设置显示颜色, Method 2:

  1. from matplotlib import font_manager as fm

  2. from  matplotlib import cm

  3. labels = s.index

  4. sizes = s.values

  5. # explode = (0.2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)  # only "explode" the 1st slice

  6. fig, ax = plt.subplots(figsize=(6,6)) # 设置绘图区域大小

  7. colors = cm.rainbow(np.arange(len(sizes))/len(sizes)) # colormaps: Paired, autumn, rainbow, gray,spring,Darks

  8. patches, texts, autotexts = ax.pie(sizes, labels=labels, autopct='%1.0f%%',

  9.        shadow=False, startangle=170, colors=colors)

  10. ax.axis('equal')  

  11. ax.set_title('Shapes -------------------', loc='left')

  12. # 重新设置字体大小

  13. proptease = fm.FontProperties()

  14. proptease.set_size('xx-small')

  15. # font size include: ‘xx-small’,x-small’,'small’,'medium’,‘large’,‘x-large’,‘xx-large’ or number, e.g. '12'

  16. plt.setp(autotexts, fontproperties=proptease)

  17. plt.setp(texts, fontproperties=proptease)

  18. plt.savefig('Demo_project_set_color_2.jpg')

  19. plt.show()

从上图可以看出,颜色显示是连续的,实现了我们想要的效果

3.4 设置图例(legend)

  1. from matplotlib import font_manager as fm

  2. from  matplotlib import cm

  3. labels = s.index

  4. sizes = s.values

  5. # explode = (0.2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)  # only "explode" the 1st slice

  6. fig, ax = plt.subplots(figsize=(6,6)) # 设置绘图区域大小

  7. colors = cm.rainbow(np.arange(len(sizes))/len(sizes)) # colormaps: Paired, autumn, rainbow, gray,spring,Darks

  8. patches, texts, autotexts = ax.pie(sizes, labels=labels, autopct='%1.0f%%',

  9.        shadow=False, startangle=170, colors=colors)

  10. ax.axis('equal')  

  11. # 重新设置字体大小

  12. proptease = fm.FontProperties()

  13. proptease.set_size('xx-small')

  14. # font size include: ‘xx-small’,x-small’,'small’,'medium’,‘large’,‘x-large’,‘xx-large’ or number, e.g. '12'

  15. plt.setp(autotexts, fontproperties=proptease)

  16. plt.setp(texts, fontproperties=proptease)

  17. ax.legend(labels, loc=2)

  18. plt.savefig('Demo_project_set_legend_error.jpg')

  19. plt.show()

从上面可看出,当类别较多时,图例(legend)的位置摆放显示有重叠,显示有些问题,需要进行调整。

3.5 重新设置图例(legend)

  1. from matplotlib import font_manager as fm

  2. from  matplotlib import cm

  3. labels = s.index

  4. sizes = s.values

  5. # explode = (0.2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)  # only "explode" the 1st slice

  6. fig, axes = plt.subplots(figsize=(10,5),ncols=2) # 设置绘图区域大小

  7. ax1, ax2 = axes.ravel()

  8. colors = cm.rainbow(np.arange(len(sizes))/len(sizes)) # colormaps: Paired, autumn, rainbow, gray,spring,Darks

  9. patches, texts, autotexts = ax1.pie(sizes, labels=labels, autopct='%1.0f%%',

  10.        shadow=False, startangle=170, colors=colors)

  11. ax1.axis('equal')  

  12. # 重新设置字体大小

  13. proptease = fm.FontProperties()

  14. proptease.set_size('xx-small')

  15. # font size include: ‘xx-small’,x-small’,'small’,'medium’,‘large’,‘x-large’,‘xx-large’ or number, e.g. '12'

  16. plt.setp(autotexts, fontproperties=proptease)

  17. plt.setp(texts, fontproperties=proptease)

  18. ax1.set_title('Shapes', loc='center')

  19. # ax2 只显示图例(legend)

  20. ax2.axis('off')

  21. ax2.legend(patches, labels, loc='center left')

  22. plt.tight_layout()

  23. plt.savefig('Demo_project_set_legend_good.jpg')

  24. plt.show()

3.6 将某些类别突出显示

  • 将某些类别突出显示

  • 控制label的显示位置

  • 控制百分比的显示位置

  • 控制突出位置的大小

  1. from matplotlib import font_manager as fm

  2. from  matplotlib import cm

  3. labels = s.index

  4. sizes = s.values

  5. explode = (0.1,0,0,0,0,0,0,0,0,0,0,0,0,0.2,0,0,0,0.1,0)  # "explode" , show the selected slice

  6. fig, axes = plt.subplots(figsize=(8,5),ncols=2) # 设置绘图区域大小

  7. ax1, ax2 = axes.ravel()

  8. colors = cm.rainbow(np.arange(len(sizes))/len(sizes)) # colormaps: Paired, autumn, rainbow, gray,spring,Darks

  9. patches, texts, autotexts = ax1.pie(sizes, labels=labels, autopct='%1.0f%%',explode=explode,

  10.        shadow=False, startangle=170, colors=colors, labeldistance=1.2,pctdistance=1.03, radius=0.4)

  11. # labeldistance: 控制labels显示的位置

  12. # pctdistance: 控制百分比显示的位置

  13. # radius: 控制切片突出的距离

  14. ax1.axis('equal')  

  15. # 重新设置字体大小

  16. proptease = fm.FontProperties()

  17. proptease.set_size('xx-small')

  18. # font size include: ‘xx-small’,x-small’,'small’,'medium’,‘large’,‘x-large’,‘xx-large’ or number, e.g. '12'

  19. plt.setp(autotexts, fontproperties=proptease)

  20. plt.setp(texts, fontproperties=proptease)

  21. ax1.set_title('Shapes', loc='center')

  22. # ax2 只显示图例(legend)

  23. ax2.axis('off')

  24. ax2.legend(patches, labels, loc='center left')

  25. plt.tight_layout()

  26. # plt.savefig("pie_shape_ufo.png", bbox_inches='tight')

  27. plt.savefig('Demo_project_final.jpg')

  28. plt.show()


更多精彩内容请关注公众号:

“Python数据之道”


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存